﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    public class TInventoryAdjustsRepository : BaseRepository<TInventoryAdjust>, ITInventoryAdjustsRepository
    {
        public TInventoryAdjustsRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }

        /// <summary>
        /// 新建库存信息
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool AddInventoryAdjusts(TInventoryAdjust item , out string message)
        {
            message = "";
            using (var tran = Context.Database.BeginTransaction())
            {
                TInventoryAdjust tInventoryList = new TInventoryAdjust();
                //var itmeid = Context.TInventoryAdjusts.Find(item.Id);
                //if (itmeid != null)
                //{
                    //单据号
                    //来源单据类型
                    //来源单据号
                    //调整数量
                    //调整原因
                    //备注
                    //创建时间
                    //创建人员ID
                    //创建人员姓名
                    tInventoryList.BillSn = item.BillSn;
                    tInventoryList.SourceType = item.SourceType;
                    tInventoryList.SourceSn = item.SourceSn;
                    tInventoryList.Qty = item.Qty;
                    tInventoryList.Reason = item.Reason;
                    tInventoryList.Remark = item.Remark;
                    tInventoryList.CreateDate = DateTime.Now;
                    tInventoryList.NowUserId = item.NowUserId;
                    tInventoryList.NowUserRealName = item.NowUserRealName;
                //}
                tInventoryList.CreateDate=DateTime.Now;
                tInventoryList.NowUserId = item.NowUserId;
                tInventoryList.NowUserRealName = item.NowUserRealName;
                //物料信息
                var Material = Context.TMaterials.Find(item.MaterialId);
                if (Material != null)
                {
                    tInventoryList.MaterialId = Material.Id;
                    tInventoryList.MaterialCode = Material.Code;
                    tInventoryList.MaterialName = Material.Name;
                }

                //仓位信息
                var location = Context.TCells.Find(item.LocationId);
                if (location != null)
                {
                    tInventoryList.LocationId = location.Id;
                    tInventoryList.LocationCode = location.Code;
                }

                //库房信息
                var house = Context.TWarehouses.Find(item.AreaId);
                if (house != null)
                {
                    tInventoryList.AreaName = house.Name;

                    // 根据 AreaName 和 WarehouseId 查询对应的库区记录
                    var area = Context.TAreas.FirstOrDefault(m =>
                        m.Name == item.AreaName && m.WhId == item.AreaId);
                }

                //货主
                var owner = Context.TOwners.Find(item.OwnerId);
                if (owner != null && owner.Status == 1)
                {

                    tInventoryList.OwnerName = owner.Name;
                }
                else
                {
                    message = "货主信息不存在或被禁用";
                    return false;
                }

                try
                {
                    if (Context.TInventoryAdjust.Add(tInventoryList) == null)
                    {
                        message = "库存调整信息添加失败";
                        tran.Rollback();
                        return false;
                    }
                    bool updLog = UpdTInvenoryLog(item);
                    if (!updLog)
                    {
                        message = "库存日志添加失败";
                        tran.Rollback();
                        return false;
                    }
              

                    Context.SaveChanges();
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    return false;
                }
            }
           

        }

        /// <summary>
        /// 插入库存流水表
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool UpdTInvenoryLog(TInventoryAdjust item)
        {
            TInventoryLog inventoryLog = new TInventoryLog();
            try
            {
                inventoryLog.SourceType = item.SourceType;
                inventoryLog.SourceSn = item.SourceSn;
                inventoryLog.WarehouseId = item.WhId;
                inventoryLog.WarehouseName = item.WhName;
                inventoryLog.AreaId = item.AreaId;
                inventoryLog.AreaName = item.AreaName;
                inventoryLog.LocationCode = item.LocationCode;
                inventoryLog.PalletBarcode = item.PalletBarcode;
                inventoryLog.OwnerId = item.OwnerId;
                inventoryLog.OwnerName = item.OwnerName;
                inventoryLog.MaterialId = item.MaterialId;
                inventoryLog.MaterialCode = item.MaterialCode;
                inventoryLog.MaterialName = item.MaterialName;
                inventoryLog.ChangeQty = item.Qty;
                decimal Snum = GetTInventoryNum(item.MaterialId);
                inventoryLog.StartQty = Snum;
                inventoryLog.EndQty = item.Qty;
                inventoryLog.Remark = item.Remark;
                inventoryLog.CreateDate = DateTime.Now;
                inventoryLog.CreateUserId = item.NowUserId;
                inventoryLog.CreateUser = item.NowUserRealName;

                Context.TInventoryLog.Add(inventoryLog);
                Context.SaveChanges();

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
           

        }

        // 根据来源单据号获取库存数量
        public decimal GetTInventoryNum(int ? MaterialId)
        {
            decimal? num = Context.TInventories
                .Where(x => x.MaterialId == MaterialId)
                .Select(x => x.AvailableQty)
                .FirstOrDefault()
                .GetValueOrDefault();

            return (decimal)num;

        }


        /// <summary>
        /// 根据库存表的ID修改库存明细表
        /// </summary>
        /// <param name="InventoryId"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public decimal? UpdateTInvenoryDetail(int InventoryId, string num)
        {
            var inventoryDetail = Context.TInventoryDetails.FirstOrDefault(x => x.InventoryId == InventoryId);

            if (inventoryDetail != null)
            {
                if (num.Contains('-'))
                {
                    num = num[1..];
                    decimal num1 = decimal.Parse(num);

                    if (num1 < 0)
                    {
                        return 0;
                    }
                    inventoryDetail.SkuNum = inventoryDetail.SkuNum -= num1;
                    return inventoryDetail.SkuNum;
                }
                else
                {
                    decimal num1 = decimal.Parse(num);

                    if (num1 < 0)
                    {
                        return 0;
                    }
                    inventoryDetail.SkuNum = inventoryDetail.SkuNum += num1;
                    return inventoryDetail.SkuNum;
                }
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 根据单据号获取并修改库存表中单据号对应的数量
        /// </summary>
        /// <param name="BillSn"></param>
        /// <returns></returns>
        public decimal? UpdTInventoryNum(decimal? MaterialId, string num)
        {
            // 查询指定物料的可用数量
            var inventory = Context.TInventories.FirstOrDefault(x => x.MaterialId == MaterialId);

            if (inventory != null)
            {
                int id = inventory.Id;
                if (id == 0)
                {
                    return null;
                }
                UpdateTInvenoryDetail(id, num);
                if (num.Contains('-'))
                {
                    num = num[1..];
                    decimal num1 = decimal.Parse(num);

                    if (num1 < 0)
                    {
                        return 0;
                    }
                    inventory.AvailableQty = inventory.AvailableQty -= num1;
                    return inventory.AvailableQty;
                }
                else
                {
                    decimal num1 = decimal.Parse(num);

                    if (num1 < 0)
                    {
                        return 0;
                    }
                    inventory.AvailableQty = inventory.AvailableQty += num1;
                    return inventory.AvailableQty;
                }
            }
            else
            {
                // 物料不存在，返回0表示未更新任何行
                return 0;
            }
        }

        /// <summary>
        /// 获取单据号
        /// </summary>
        /// <returns></returns>
        public string AddDocumentNumber()
        {
            DateTime now = DateTime.Now;

            string year = now.Year.ToString();
            string month = now.Month.ToString().PadLeft(2, '0'); // 在月份前补零，确保两位数格式
            string day = now.Day.ToString().PadLeft(2, '0');
            string hour = now.Hour.ToString().PadLeft(2, '0');
            string minute = now.Minute.ToString().PadLeft(2, '0');
            string second = now.Second.ToString().PadLeft(2, '0');
            string millisecond = now.Millisecond.ToString().PadLeft(3, '0'); // 在毫秒前补零，确保三位数格式
            Stopwatch stopwatch = new Stopwatch();
            long elapsedMicroseconds = stopwatch.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
            string elapsedMicrosecondsString = elapsedMicroseconds.ToString();

            string datetimeString = "A" + year + month + day + hour + minute + second + millisecond + elapsedMicrosecondsString;

            return datetimeString;
        }

        /// <summary>
        /// 根据物料查询信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public List<TInventoryAdjustmentDTO> GetWarehouse(int Id)
        {
            var list = Context.TInventories.AsQueryable();

            if (Id != 0)
            {
                list = list.Where(x => x.MaterialId == Id);
            }

            var DTO = new List<TInventoryAdjustmentDTO>();
            DTO = list.Select(x => new TInventoryAdjustmentDTO()
            {
                MaterialId = x.MaterialId,
                AreaId = x.AreaId,
                AreaName = x.AreaName,
                LocationId = x.LocationId,
                LocationCode = x.LocationCode,
                OwnerId = x.OwnerId,
                OwnerName = x.OwnerName,
            }).ToList();

            return DTO;
        }


        /// <summary>
        /// 库存调整查询
        /// </summary>
        /// <param name="totalCount"></param>
        /// <param name="WhId"></param>
        /// <param name="AreaId"></param>
        /// <param name="Status"></param>
        /// <param name="BillSn"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<TInventoryAdjust> GetInventoryAdjusts(out int totalCount, int? WhId, int? AreaId, int? Status, string? BillSn,
            int pageIndex, int pageSize)
        {
            var list = Context.TInventoryAdjust.AsQueryable();

            if (WhId.HasValue)
            {
                list = list.Where(x => x.WhId == WhId);
            }
            if (AreaId.HasValue)
            {
                list = list.Where(x => x.AreaId == AreaId);
            }
            if (Status.HasValue)
            {
                list = list.Where(x => x.Status == Status);
            }
            if (BillSn != null)
            {
                list = list.Where(x => x.BillSn.Contains(BillSn));
            }
            totalCount = list.Count();

            list = list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);

            return list.ToList();
        }

        /// <summary>
        /// 根据ID获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TInventoryAdjust GetInventoryAdjustsById(int id)
        {
            try
            {
                return Context.TInventoryAdjusts.Find(id);
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 更新库存信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdateInventoryAdjusts(TInventoryAdjust model)
        {
            try
            {
                model.ModifyDate = DateTime.Now;
                model.ModifyUserId = model.NowUserId;
                Context.Update(model);

                int count = Context.SaveChanges();
                if (count > 0)
                    return true;
                return false;

            }
            catch
            {
                // 处理异常，如记录日志等
                return false;
            }
        }

        /// <summary>
        /// 更新库存信息审核同意
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdateReviewConsent(TInventoryApproveDTO model)
        {

            var robj = Context.TInventoryAdjusts.Find(model.Id);
            var getJobNO = Context.TUsers.AsQueryable()
                .Where(x => x.Id == model.NowUserId)
                .Select(x => x.JobNo == model.JobNO);

            if (robj != null && model.Status == 0)
            {
                robj.Status = 1;
                robj.NowUserId = model.NowUserId;
                robj.Remark = model.Remark;
                robj.ModifyDate = DateTime.Now;

                if (!InsertTAuditRecords(model))
                {
                    return false;
                }

            }
            else
            {
                return false;
            }

            Context.TInventoryAdjusts.Update(robj);

            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 更新库存信息审核驳回
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdateReviewRejection(TInventoryApproveDTO model)
        {
            var robj = Context.TInventoryAdjusts.Find(model.Id);
            var getJobNO = Context.TUsers.AsQueryable()
                .Where(x => x.Id == model.NowUserId)
                .Select(x => x.JobNo == model.JobNO);

            if (robj != null && model.Status == 0)
            {
                robj.Status = 3;
                robj.NowUserId = model.NowUserId;
                robj.Remark = model.Remark;
                robj.ModifyDate = DateTime.Now;

                if (!InsertTAuditRecords(model))
                {
                    return false;
                }

            }
            else
            {
                return false;
            }

            Context.TInventoryAdjusts.Update(robj);

            return Context.SaveChanges() > 0;
        }

        /*
        /// <summary>
        /// 库存信息审核方法封装
        /// </summary>
        /// <param name="model"></param>
        /// <param name="condition"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        private bool GetTInventoryAdjust(TInventoryApproveDTO model, int condition, int status)
        {
            var robj = Context.TInventoryAdjusts.Find(model.Id);
            var getJobNO = Context.TUsers.AsQueryable()
                .Where(x => x.Id == model.NowUserId)
                .Select(x => x.JobNo == model.JobNO);

            if (robj != null && model.Status == condition)
            {
                robj.Status = status;
                robj.NowUserId = model.NowUserId;
                robj.Remark = model.Remark;
                robj.ModifyDate = DateTime.Now;

                if (!InsertTAuditRecords(model))
                {
                    return false;
                }

            }
            else
            {
                return false;
            }

            Context.TInventoryAdjusts.Update(robj);

            return Context.SaveChanges() > 0;
        }
        */

        /// <summary>
        /// 根据当前用户ID查询用户工号
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<TUser> GetJobNumberByNowUser(int id)
        {

            var list = Context.TUsers.AsQueryable();
            if (id != 0)
            {
                list = list.Where(x => x.Id == id);
            }

            return list.ToList();
        }

        /// <summary>
        /// 插入日志
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private bool InsertTAuditRecords(TInventoryApproveDTO model)
        {

            var robj = Context.TAuditRecord.Add(new TAuditRecord());

            if (robj != null)
            {
                robj.Entity.RecordType = 5;
                robj.Entity.AuditUserId = model.NowUserId;
                robj.Entity.AuditUserName = model.NowUserRealName;
                robj.Entity.AuditTime = DateTime.Now;
                if (model.Status == 0)
                {
                    robj.Entity.AuditStatus = 1;
                }
                else if (model.Status == 1)
                {
                    robj.Entity.AuditStatus = 2;
                }

                robj.Entity.Remark = model.Remark;
            }

            try
            {
                Context.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                // 处理异常，如记录日志等
                return false;
            }
        }

        /// <summary>
        /// 更新审核状态为已调整
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdApproved(int id)
        {
            var item = Context.TInventoryAdjust.FirstOrDefault(x => x.Id == id);
            
            if (id <= 0)
            {
                return false;
            }
            if (item == null)
            {
                return false;
            }
            if (item.Qty == 0 || item.Qty == null)
            {
                return false;
            }

            string num = item.Qty.ToString();

            UpdTInventoryNum(item.MaterialId, num);
            item.Status = 2;
            Context.Update(item);
            return Context.SaveChanges() > 0;
        }
    }
}
